#include "store.h"
#include <iostream>
#include <memory>
#include <iomanip>

using namespace StoreSystem;

//StoreItem

StoreItem::StoreItem(const std::string& itemName, const std::string& description, int price)
    : name(itemName), description(description), price(price) {}

std::string StoreItem::getName() const {
    return name;
}

std::string StoreItem::getDescription() const {
    return description;
}

int StoreItem::getPrice() const {
    return price;
}

void StoreItem::displayDetails() const {
    std::cout << std::left << std::setw(25) << name
        << std::setw(15) << price << "金币"
        << description << std::endl;
}

//Consumable

Consumable::Consumable(const std::string& itemName, const std::string& description,
    int price, int effectValue)
    : StoreItem(itemName, description, price), effectValue(effectValue) {}

int Consumable::getEffectValue() const {
    return effectValue;
}

void Consumable::displayDetails() const {
    StoreItem::displayDetails();
}

//Accessory

Accessory::Accessory(const std::string& itemName, const std::string& description,
    int price, int boostValue)
    : StoreItem(itemName, description, price), boostValue(boostValue) {}

int Accessory::getBoostValue() const {
    return boostValue;
}

void Accessory::displayDetails() const {
    StoreItem::displayDetails();
}

//消耗品子类

HealthPotion::HealthPotion(const std::string& itemName, int effectValue, int price)
    : Consumable(itemName, "恢复" + std::to_string(effectValue) + "点生命值",
        price, effectValue) {}

ManaPotion::ManaPotion(const std::string& itemName, int effectValue, int price)
    : Consumable(itemName, "恢复" + std::to_string(effectValue) + "点法力值",
        price, effectValue) {}

Incense::Incense(const std::string& itemName, int effectValue, int price)
    : Consumable(itemName, "恢复" + std::to_string(effectValue) + "点理智值",
        price, effectValue) {}

//饰品子类

LuckAccessory::LuckAccessory(const std::string& itemName, int boostValue, int price)
    : Accessory(itemName, "幸运+" + std::to_string(boostValue), price, boostValue) {}

AccuracyAccessory::AccuracyAccessory(const std::string& itemName, int boostValue, int price)
    : Accessory(itemName, "准确度+" + std::to_string(boostValue), price, boostValue) {}

DodgeAccessory::DodgeAccessory(const std::string& itemName, int boostValue, int price)
    : Accessory(itemName, "躲避+" + std::to_string(boostValue), price, boostValue) {}

AgilityAccessory::AgilityAccessory(const std::string& itemName, int boostValue, int price)
    : Accessory(itemName, "敏捷+" + std::to_string(boostValue), price, boostValue) {}

//装备子类

Shoe::Shoe(const std::string& itemName, const std::string& boostType, int boostValue, int price)
    : Accessory(itemName, boostType + "+" + std::to_string(boostValue), price, boostValue),
    boostType(boostType) {}

void Shoe::displayDetails() const {
    std::cout << std::left << std::setw(25) << name
        << std::setw(15) << price << "金币"
        << boostType << " +" << getBoostValue() << std::endl;
}

Helmet::Helmet(const std::string& itemName, const std::string& boostType, int boostValue, int price)
    : Accessory(itemName, boostType + "+" + std::to_string(boostValue), price, boostValue),
    boostType(boostType) {}

void Helmet::displayDetails() const {
    std::cout << std::left << std::setw(25) << name
        << std::setw(15) << price << "金币"
        << boostType << " +" << getBoostValue() << std::endl;
}

Weapon::Weapon(const std::string& itemName, const std::string& boostType, int boostValue, int price)
    : Accessory(itemName, boostType + "+" + std::to_string(boostValue), price, boostValue),
    boostType(boostType) {}

void Weapon::displayDetails() const {
    std::cout << std::left << std::setw(25) << name
        << std::setw(15) << price << "金币"
        << boostType << " +" << getBoostValue() << std::endl;
}

Armor::Armor(const std::string& itemName, const std::string& boostType, int boostValue, int price)
    : Accessory(itemName, boostType + "+" + std::to_string(boostValue), price, boostValue),
    boostType(boostType) {}

void Armor::displayDetails() const {
    std::cout << std::left << std::setw(25) << name
        << std::setw(15) << price << "金币"
        << boostType << " +" << getBoostValue() << std::endl;
}

//Store

Store::Store() {
    initializeInventory();
}

void Store::initializeInventory() {
    //生命药水
    addItem(std::make_unique<HealthPotion>("凝痂血菇", 15, 25));
    addItem(std::make_unique<HealthPotion>("地穴蛞蝓粘液", 30, 50));
    addItem(std::make_unique<HealthPotion>("活体肉瘤萃取物", 50, 100));

    //法力药水
    addItem(std::make_unique<ManaPotion>("苔藓脑质", 10, 20));
    addItem(std::make_unique<ManaPotion>("垂涎者脊髓液", 25, 45));
    addItem(std::make_unique<ManaPotion>("沉睡巢母脑脊液", 40, 80));

    //熏香
    addItem(std::make_unique<Incense>("鼠尾草与劣梦混合物", 10, 30));
    addItem(std::make_unique<Incense>("拾荒者安宁粉尘", 20, 55));
    addItem(std::make_unique<Incense>("哑巴僧侣的静默", 35, 90));

    //幸运饰品
    addItem(std::make_unique<LuckAccessory>("污秽的骰子", 5, 40));
    addItem(std::make_unique<LuckAccessory>("四趾兔脚", 8, 70));

    //准确度饰品
    addItem(std::make_unique<AccuracyAccessory>("磨制的凝视之眼", 5, 45));
    addItem(std::make_unique<AccuracyAccessory>("校准的指南腺体", 10, 85));

    //躲避饰品
    addItem(std::make_unique<DodgeAccessory>("褪色的潜行蜥蜴皮", 5, 40));
    addItem(std::make_unique<DodgeAccessory>("无声蝙蝠的耳骨", 8, 75));

    //敏捷饰品
    addItem(std::make_unique<AgilityAccessory>("肌腱编织指环", 5, 42));
    addItem(std::make_unique<AgilityAccessory>("焦躁地精的趾环", 8, 78));

    //鞋子
    addItem(std::make_unique<Shoe>("杂斑猎犬皮便鞋", "敏捷", 10, 60));
    addItem(std::make_unique<Shoe>("无声鼹鼠皮靴", "躲避", 15, 85));
    addItem(std::make_unique<Shoe>("剥制潜地兽胫甲", "敏捷", 20, 120));

    //头盔
    addItem(std::make_unique<Helmet>("锈蚀的铁皮头罩", "力量", 10, 65));
    addItem(std::make_unique<Helmet>("缝合知识兜帽", "智力", 15, 90));
    addItem(std::make_unique<Helmet>("镶嵌复眼的窥视盔", "准确度", 20, 130));

    //武器
    addItem(std::make_unique<Weapon>("碎骨者（粗大胫骨）", "力量", 15, 100));
    addItem(std::make_unique<Weapon>("精准刺管（某种生物毒刺）", "准确度", 25, 150));
    addItem(std::make_unique<Weapon>("掘洞巫婆的搅杖", "智力", 30, 180));

    //防具
    addItem(std::make_unique<Armor>("废料与骨片拼合盾", "躲避", 15, 110));
    addItem(std::make_unique<Armor>("硬化甲壳胸甲", "力量", 20, 140));
    addItem(std::make_unique<Armor>("苦修者的刺猬披肩", "理智", 25, 160));
}

void Store::addItem(std::unique_ptr<StoreItem> item) {
    inventory.push_back(std::move(item));
}

void Store::displayInventory() const {
    std::cout << "\n===== 商店库存 =====" << std::endl;
    std::cout << std::left << std::setw(5) << "编号"
        << std::setw(25) << "物品名称"
        << std::setw(15) << "价格"
        << "效果" << std::endl;
    std::cout << std::string(65, '-') << std::endl;

    for (int i = 0; i < inventory.size(); i++) {
        std::cout << std::setw(5) << (i + 1);
        inventory[i]->displayDetails();
    }
}

bool Store::purchaseItem(int index, int& playerMoney) {
    if (index < 0 || index >= inventory.size()) {
        std::cout << "无效的商品编号！" << std::endl;
        return false;
    }

    const int itemPrice = inventory[index]->getPrice();
    if (playerMoney < itemPrice) {
        std::cout << "金币不足，无法购买 " << inventory[index]->getName() << "！" << std::endl;
        return false;
    }

    playerMoney -= itemPrice;
    std::cout << "成功购买 " << inventory[index]->getName()
        << "，花费 " << itemPrice << " 金币！" << std::endl;

    //从商店移除已购买的商品
    inventory.erase(inventory.begin() + index);
    return true;
}